package com.mjk.dubbo.impl;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import com.alibaba.dubbo.config.annotation.Service;
import com.mjk.common.base.error.BeeError;
import com.mjk.common.base.error.BizException;
import com.mjk.common.base.response.BeeResponse;
import com.mjk.common.base.work.annotation.BeeWork;
import com.mjk.common.tools.gson.GsonUtils;
import com.mjk.common.tools.logger.BizLogger;
import com.mjk.common.util.*;
import com.mjk.common.web.getway.transfer.cloud.CloudGetWayProtocol;
import com.mjk.common.web.getway.transfer.dubbo.DubboGetWayProtocol;
import com.mjk.dubbo.CommonManagerApiInterface;
import org.springframework.beans.BeansException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.transaction.annotation.Transactional;


@Service
@ConditionalOnBean(value = DubboGetWayProtocol.class)
public class DubboService implements CommonManagerApiInterface, ApplicationContextAware {
	public Map<String, Object> workMapping = new ConcurrentHashMap<String, Object>();

	public Object getWork(String work) {
		Object o = workMapping.get(work.toUpperCase());
		if (null != o) {
			return o;
		} else {
			throw new BizException(BeeError.SYSTEM_INSTANCE_IS_NULL.getMsg());
		}
	}

	@Override
	@Transactional
	public BeeResponse doCommonApi(String work, String method, String dictJson) {
		if (ObjectUtils.isEmpty(work)) {
			throw new BizException("work is null");
		}
		try {
			Object o = getWork(work);
			Method m = ReflectionUtils.getMethod(o.getClass(), method);
			Class<?> clazz = ClassUtil.loadClass(m.getParameters()[0].getParameterizedType().getTypeName());
			Object paramter = BeanUtils.mapToBeanIgnoreCase(GsonUtils.json2Map(dictJson), clazz);
			Object result = m.invoke(o, new Object[]{paramter});
			if (ObjectUtils.isEmpty(result)) {
				return BeeError.BEE_ERROR_FOR_ADMIN.tranceError();
			}
			return (BeeResponse) result;
		} catch (Exception e) {
			BizLogger.error(e);
			return BeeError.BEE_ERROR_FOR_ADMIN.tranceError(BeeError.BEE_ERROR_FOR_ADMIN.getCode(),
					ObjectUtils.isEmpty(e.getMessage()) ? e.getCause().getMessage() : e.getMessage(), null);
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		Map<String, Object> beas = applicationContext.getBeansWithAnnotation(BeeWork.class);
		for (Entry<String, Object> entry : beas.entrySet()) {
			//此处有可能回出现代理对象，如果是代理对象要转为非代理对象
			BeeWork work = AopTargetUtils.getTarget(entry.getValue()).getClass().getAnnotation(BeeWork.class);

			workMapping.put(work.work().toUpperCase(), AopTargetUtils.getTarget(entry.getValue()));
		}
	}

}
